<template>
  <div ref="line" class="timeline-container">
    <section
      ref="timeline"
      :class="{
        'is-horizontal': direction === 'horizontal'
      }"
    >
      <div
        v-for="(point, index) in activities"
        :key="point.content.procname"
        :class="{
          'time-point': true,
          'is-disabled': point.disabled
        }"
      >
        <div class="timeline__node">
          <el-tooltip
            :disabled="isPanelShow"
            :effect="theme === 'dark' ? 'light' : 'dark'"
            :content="point.label"
            placement="top"
          >
            <div class="dot" @click="onDotClick(point)">
              <span v-if="point.content.procname === active" class="operable active">
                <svg width="26px" height="26px" class="svg outside">
                  <circle
                    class="slot"
                    r="10"
                    cy="13"
                    cx="13"
                    stroke-width="2"
                    stroke-linejoin="round"
                    stroke-linecap="round"
                    fill="none"
                  />
                  <circle
                    class="progress"
                    r="10"
                    cy="13"
                    cx="13"
                    stroke-width="2"
                    stroke="#1593FF"
                    stroke-linejoin="round"
                    stroke-linecap="round"
                    fill="none"
                    stroke-dashoffset="0px"
                    stroke-dasharray="461px"
                  />
                </svg>
                <svg width="20px" height="20px" class="svg inside">
                  <circle
                    class="slot"
                    r="5"
                    cy="10"
                    cx="10"
                    stroke-width="2"
                    stroke-linejoin="round"
                    stroke-linecap="round"
                    fill="none"
                  />
                  <circle
                    class="progress"
                    r="5"
                    cy="10"
                    cx="10"
                    stroke-width="2"
                    stroke="#1593FF"
                    stroke-linejoin="round"
                    stroke-linecap="round"
                    fill="none"
                    stroke-dashoffset="0px"
                    stroke-dasharray="461px"
                  />
                </svg>
                <span class="point" />
              </span>
              <span v-else-if="point.type === 'completed'" class="completed">
                <i class="iconfont icon-seleted"></i>
              </span>
              <span v-else class="uncompleted">
                <i class="iconfont icon-to-do"></i>
              </span>
            </div>
          </el-tooltip>
          <div v-if="index !== activities.length - 1" class="line">
            <span class="normal">
              <span
                class="completed"
                :style="{
                  height: point.type === 'completed' ? '100%' : '0',
                  width: point.type === 'completed' ? '100%' : '0'
                }"
              />
            </span>
          </div>
        </div>
        <div
          v-if="isPanelShow"
          class="timeline_wrapper"
          @click="onDotClick(point)"
          :style="wrapperColor(point.content.status)"
        >
          <div class="timeline_card">
            <div class="row header">
              <span>{{ point.content.procname }}</span>
              <span>{{ point.content.status }}</span>
            </div>
            <div class="row">操作人：{{ point.content.operator | isEmptyString }}</div>
            <div class="row">保存时间：{{ point.content.time | isEmptyString }}</div>
          </div>
        </div>
      </div>
    </section>
    <div v-if="isFold" class="tool">
      <div class="open-button" @click="operatePanel">
        <i
          :class="{
            iconfont: true,
            'icon-arrow-right': !isPanelShow,
            'icon-arrow-left': isPanelShow
          }"
        ></i>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { deepClone } from '@/utils/specificFunc'
import Vue from 'vue'
import { Component, Emit, Prop, Ref } from 'vue-property-decorator'
import { Getter } from 'vuex-class'
import { TimeLineSetting } from '@/interface/Basic'
@Component({
  filters: {
    isEmptyString(val: string) {
      if (val === '') return '无'
      else return val
    }
  }
})
class TimeLine extends Vue {
  @Ref() timeline!: HTMLElement
  @Getter('theme') theme!: 'light' | 'dark'
  @Prop({ required: true }) timelineArray!: TimeLineSetting[]
  @Prop({ required: true }) current!: string
  @Prop({ default: true }) isFold!: boolean
  @Prop({ default: 'vertical' }) direction!: 'vertical' | 'horizontal'
  @Prop() wrapperColor!: (status: string) => string
  isPanelShow: boolean = true
  get activities() {
    return deepClone(this.timelineArray)
  }
  get active() {
    if (!this.current) return this.activities[0].name
    return this.current
  }
  // methods
  @Emit()
  onDotClick(dotMessage: TimeLineSetting) {
    return dotMessage
  }
  @Emit('onPanelClose')
  operatePanel() {
    const { width: first_width } = this.timeline.getBoundingClientRect()
    this.isPanelShow = !this.isPanelShow
    this.$nextTick(() => {
      const { width: last_width } = this.timeline.getBoundingClientRect()
      this.timeline.animate([{ width: first_width + 'px' }, { width: last_width + 'px' }], {
        duration: 200
      })
    })
    return this.isPanelShow
  }
}
export default TimeLine
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
.timeline-container {
  position: relative;
  box-sizing: border-box;
  padding: 10px;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  section {
    box-sizing: border-box;
    padding: 0 5px;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    z-index: 2;
    transition: all 0.2s ease;
    overflow-y: auto;
  }
  .is-horizontal {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    .time-point {
      flex-direction: inherit;
      .timeline__node {
        flex-direction: inherit;
        .line {
          .normal {
            height: 2px;
            width: 60px;
          }
        }
      }
    }
  }
  .time-point {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    .timeline__node {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: flex-start;
    }
    .timeline_wrapper {
      min-width: 200px;
      height: 90%;
      margin: 10px;
      margin-top: 5px;
      background-color: #ffffff;
      cursor: pointer;
      .timeline_card {
        height: 100%;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        justify-content: space-between;
        box-sizing: border-box;
        padding: 10px;
        font-size: 12px;
        overflow: hidden;
        #shadow-color(0, 0, 2px, 0, --primary-shadow-color);
        .header {
          width: 100%;
          display: flex;
          align-items: baseline;
          justify-content: space-between;
        }
      }
    }
  }
  .is-disabled {
    filter: grayscale(100%);
  }
  .dot {
    width: 100%;
    font-size: 12px;
    z-index: 2;
    cursor: pointer;
    span {
      position: relative;
      display: block;
      width: 25px;
      height: 25px;
      text-align: center;
      line-height: 25px;
      border-radius: 50%;
      #bg-color(--primary-bg-color);
      i {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        color: #ffffff;
      }
    }
    .completed {
      #bg-color(--primary-green-color);
    }
    .uncompleted {
      #color(background-color, --primary-blue-color);
      i {
        color: #ffffff;
      }
    }
    .operable {
      .svg,
      .point {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        .slot {
          #color(stroke, --primary-bg-color);
        }
        .progress {
          #color(stroke, --primary-blue-color);
        }
      }
      .point {
        display: block;
        width: 3px;
        height: 3px;
        border-radius: 50%;
        #color(background-color, --primary-blue-color);
      }
    }
    .active {
      .outside {
        .progress {
          stroke-dashoffset: -20px;
        }
        animation: svgrotate 5s linear infinite reverse;
      }
      .inside {
        .progress {
          stroke-dasharray: 5px;
        }
        animation: svgrotate 3s linear infinite;
      }
    }
  }
  .line {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    margin-top: -2px;
    span {
      display: block;
      width: 2px;
      height: 60px;
      border-radius: 10px;
      z-index: 1;
      #color(background-color, --heavier-border-color);
    }
    .normal {
      position: relative;
      overflow: hidden;
    }
    .completed {
      position: absolute;
      transition: all 0.5s ease;
      #color(background-color, --primary-green-color);
    }
  }
  .tool {
    position: absolute;
    top: 50%;
    right: 0;
    transform: translate(50%, -50%);
    .open-button {
      position: relative;
      padding: 8px;
      border-radius: 50%;
      cursor: pointer;
      #color(background-color, --module-bg-color);
      #shadow-color(2px, 0, 2px, 0, --primary-shadow-color);
      i {
        #color(color, --primary-text-color);
      }
    }
    .open-button::before {
      content: '';
      position: absolute;
      top: 0;
      left: 50%;
      transform: translate(0%, -70%);
      display: block;
      width: 10px;
      height: 10px;
      background-color: transparent;
      border-radius: 0 0 0 15px;
      box-shadow: -4px 4px 0 3px #light[ @--module-bg-color];
      [data-theme='dark'] & {
        box-shadow: -4px 4px 0 3px #dark[ @--module-bg-color];
      }
    }
    .open-button::after {
      content: '';
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translate(0%, 70%);
      display: block;
      width: 10px;
      height: 10px;
      background-color: transparent;
      border-radius: 15px 0 0 0;
      box-shadow: -4px -4px 0 3px #light[ @--module-bg-color];
      [data-theme='dark'] & {
        box-shadow: -4px -4px 0 3px #dark[ @--module-bg-color];
      }
    }
    .isOpened {
      transform: rotate(180deg);
    }
    .isOpened::before {
      transform: translate(-100%, -67%);
      border-radius: 0 0 15px 0px;
      box-shadow: 3px 3px 0 3px #light[ @--primary-bg-color];
      [data-theme='dark'] & {
        box-shadow: 3px 3px 0 3px #dark[ @--primary-bg-color];
      }
    }
    .isOpened::after {
      transform: translate(-95%, 80%);
      border-radius: 0 15px 0 0;
      box-shadow: 3px -3px 0 3px #light[ @--primary-bg-color];
      [data-theme='dark'] & {
        box-shadow: 3px -3px 0 3px #dark[ @--primary-bg-color];
      }
    }
  }
}
.scaleout-enter-active,
.scaleout-leave-active {
  transform-origin: left;
  transition: all 1s ease;
}
.scaleout-enter,
.scaleout-leave-to {
  transform: scaleX(0);
}
.scaleout-enter-to,
.scale-out-leave {
  transform: scaleX(1);
}
@keyframes svgrotate {
  0% {
    transform: translate(-50%, -50%) rotate(0);
  }
  100% {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
::-webkit-scrollbar {
  width: 0;
  height: 0;
}
</style>
